/*
 *    Copyright (c) 2018-2025, proj All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the proj developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: proj
 */
package com.ykht.proj.coupon.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.codingapi.tx.annotation.TxTransaction;
import com.ykht.proj.activity.api.feign.RemoteVInfoService;
import com.ykht.proj.activity.entity.VOrderCard;
import com.ykht.proj.common.core.constant.CommonConstants;
import com.ykht.proj.common.core.util.R;
import com.ykht.proj.common.security.util.SecurityUtils;
import com.ykht.proj.coupon.Enum.FxReturnTypeEnum;
import com.ykht.proj.coupon.Enum.FxStatusEnum;
import com.ykht.proj.coupon.entity.*;
import com.ykht.proj.coupon.mapper.FxBrandMoneyFlowMapper;
import com.ykht.proj.coupon.mapper.FxConfBrandPersonMapper;
import com.ykht.proj.coupon.mapper.FxRewardPersonMapper;
import com.ykht.proj.coupon.service.*;
import com.ykht.proj.coupon.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;

/**
 * c端奖励记录表
 *
 * @author proj code generator
 * @date 2021-08-12 14:10:39
 */
@Service
@Slf4j
@SuppressWarnings("all")
public class FxRewardPersonServiceImpl extends ServiceImpl<FxRewardPersonMapper, FxRewardPerson> implements FxRewardPersonService {

	@Autowired
	private FxRewardPersonMapper fxRewardPersonMapper;
	@Autowired
	private RemoteVInfoService remoteVInfoService;
	@Autowired
	private FxPersonAccountService fxPersonAccountService;
	@Autowired
	private FxPersonFyService fxPersonFyService;
	@Autowired
	private FxConfBrandPersonMapper fxConfBrandPersonMapper;
	@Autowired
	private FxConfBrandPersonService fxConfBrandPersonService;
	@Autowired
	private FxBrandMoneyFlowMapper fxBrandMoneyFlowMapper;

	@Override
	public MyStatistics myStatistics() {
		MyStatistics myStatistics = new MyStatistics();
		Long loginId = SecurityUtils.getPersonId();
		//金额
		FxPersonAccount account = fxPersonAccountService.getOne(Wrappers.lambdaQuery(FxPersonAccount.class).eq(FxPersonAccount::getPersonId, loginId));
		boolean b = account != null;

		myStatistics.setBalance(b?account.getBalance():BigDecimal.ZERO);
		myStatistics.setBalanceTotal(b?account.getBalanceTotal():BigDecimal.ZERO);
		List<FxRewardPerson> list = this.list(Wrappers.lambdaQuery(FxRewardPerson.class).select(FxRewardPerson::getMoney)
				.eq(FxRewardPerson::getPersonId, loginId).eq(FxRewardPerson::getStatus,Integer.valueOf(2)).between(FxRewardPerson::getCreateTime, LocalDateTime.of(LocalDate.now(), LocalTime.MIN), LocalDateTime.now()));

		list.stream().map(FxRewardPerson::getMoney).reduce(BigDecimal::add).ifPresent(o->{
			myStatistics.setTodayMoney(o);
		});
		//订单
		myStatistics.setTodayOrder(list.size());
		int count = this.count(Wrappers.lambdaQuery(FxRewardPerson.class).eq(FxRewardPerson::getPersonId, loginId).eq(FxRewardPerson::getStatus, Integer.valueOf(2)));
		//订单数
		myStatistics.setOrderNum(count);
		//饭友
		int fyCount = fxPersonFyService.count(Wrappers.lambdaQuery(FxPersonFy.class).eq(FxPersonFy::getPerId,loginId));
		myStatistics.setFyNum(fyCount);
		//卡
		R<Integer> r =  remoteVInfoService.myVinfoCount(loginId);
		if (r.getCode()== CommonConstants.SUCCESS) {
			myStatistics.setCardNum(r.getData());
		}
		return myStatistics;
	}

	@Override
	public Page<MyFy> myFys(Page page, Long personId) {
		return  fxRewardPersonMapper.myFys(page,personId);
	}

	/**
	 * 分页查询 c端奖励记录表
	 *
	 * @param page             分页对象
	 * @param fxRewardPersonVo c端奖励记录表
	 * @return
	 */
	@Override
	public IPage<FxRewardPersonVo> getFxRewardPersonPage(Page page, FxRewardPersonVo fxRewardPersonVo) {
		return fxRewardPersonMapper.getFxRewardPersonPage(page, fxRewardPersonVo);
	}

	/**
	 * 分页查询 品牌的消费记录表
	 *
	 * @param page             分页对象
	 * @param fxRewardPersonVo c端奖励记录表
	 * @return
	 */
	@Override
	public IPage<FxRewardPersonVo> getBrandConsumptionPage(Page page, FxRewardPersonVo fxRewardPersonVo) {
		return fxRewardPersonMapper.getBrandConsumptionPage(page, fxRewardPersonVo);
	}

	@Override
	public List<FxRewardPersonVo> getBrandConsumptionPage(FxRewardPersonVo fxRewardPersonVo) {
		return fxRewardPersonMapper.getBrandConsumptionPage(fxRewardPersonVo);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void rewardByShareCoupon(FxShare share, CnCouponLog cnCouponLog) {
		FxShareBrowse browse = new FxShareBrowse().selectOne(Wrappers.lambdaQuery(FxShareBrowse.class).eq(FxShareBrowse::getShareId,share.getId()).eq(FxShareBrowse::getPerId,SecurityUtils.getPersonId()));
		if (browse == null) {
			browse = new FxShareBrowse();
		}
		FxConfBrandPerson fxConfBrandPerson = fxConfBrandPersonService.findEnableConf(cnCouponLog.getBrandId());
		if (fxConfBrandPerson!=null&&fxConfBrandPerson.getSurplusPushNum()>0) {
			FxRewardPerson rewardPerson = new FxRewardPerson();
			rewardPerson.setOrderNumber(cnCouponLog.getCouponNumber());
			rewardPerson.setCompanyId(cnCouponLog.getCompanyId());
			rewardPerson.setBrandId(cnCouponLog.getBrandId());
			rewardPerson.setType(share.getType());
			rewardPerson.setShopType(1);
			rewardPerson.setShareId(share.getId());
			rewardPerson.setSingleId(share.getSingleId());
			rewardPerson.setBrowseId(browse.getId());
			rewardPerson.setStatus(0);//0已领取1佣金待发放2佣金已发放
			rewardPerson.setConfBrandPersonId(fxConfBrandPerson.getId());
//			rewardPerson.setMoney(fxConfBrandPerson.getReturnMoney());
			rewardPerson.setUseMoney(cnCouponLog.getCnMoney());
			rewardPerson.setTatId(cnCouponLog.getId());
			rewardPerson.setPersonId(share.getPerId());
			rewardPerson.setFyId(cnCouponLog.getRecipientId());
			rewardPerson.setCreateUser(SecurityUtils.getPersonId());
			rewardPerson.setCreateTime(LocalDateTime.now());
			this.save(rewardPerson);
			//更新优惠券返佣信息
//			cnCouponLog.setReturnMoney(fxConfBrandPerson.getReturnMoney());
			cnCouponLog.setShareId(share.getId());
			cnCouponLog.setShareUserId(share.getPerId());
			cnCouponLog.setFxStatus(FxStatusEnum.UN_FEEDBACK.getValue());
			cnCouponLog.setConfBrandPersonId(fxConfBrandPerson.getId());
			cnCouponLog.updateById();
			log.info("->插入返佣数据：{}",rewardPerson);
			//添加饭友，不分品牌，只要是没有和分享人绑定关系的用户都需要添加
			checkAndAddPersonFy(share,cnCouponLog);
		}

	}

	@Override
	@TxTransaction
	public void rewardByShareCard(VOrderCardVO orderCard) {
		FxShare share = new FxShare().selectById(orderCard.getShareId());
		if (share != null) {
			FxShareBrowse browse = new FxShareBrowse().selectOne(Wrappers.lambdaQuery(FxShareBrowse.class).eq(FxShareBrowse::getShareId,share.getId()).eq(FxShareBrowse::getPerId,SecurityUtils.getPersonId()));
			if (browse == null) browse = new FxShareBrowse();
			FxRewardPerson rewardPerson = new FxRewardPerson();
			rewardPerson.setOrderNumber(orderCard.getOrderCode());
			rewardPerson.setType(share.getType());
			rewardPerson.setShopType(1);
			rewardPerson.setShareId(share.getId());
			rewardPerson.setSingleId(share.getSingleId());
			rewardPerson.setBrowseId(browse.getId());
			rewardPerson.setStatus(0);//0已领取1佣金待发放2佣金已发放
			rewardPerson.setTatId(orderCard.getId());
			rewardPerson.setPersonId(share.getPerId());
			rewardPerson.setFyId(orderCard.getPersonId());
			rewardPerson.setCreateUser(SecurityUtils.getPersonId());
			rewardPerson.setCreateTime(LocalDateTime.now());
			this.save(rewardPerson);
			log.info("->插入返佣数据：{}",rewardPerson);
			//添加饭友，不分品牌，只要是没有和分享人绑定关系的用户都需要添加
			this.addFy(share,orderCard.getPersonId(),orderCard.getId());
		}


	}

	private void checkAndAddPersonFy(FxShare share, CnCouponLog cnCouponLog) {
		this.addFy(share,cnCouponLog.getRecipientId(),cnCouponLog.getId());
	}


	private void addFy(FxShare share,Long fyId,Long tatId) {
		Integer count = new FxPersonFy().selectCount(Wrappers.lambdaQuery(FxPersonFy.class).eq(FxPersonFy::getPerId, share.getPerId()).eq(FxPersonFy::getFyId, fyId));
		if (count == 0 ){
			FxPersonFy personFy = new FxPersonFy();
			personFy.setPerId(share.getPerId());
			personFy.setFyId(fyId);
			personFy.setShareId(share.getId());
			personFy.setInviteType(share.getShopType());
			personFy.setTatId(tatId);
			personFy.setCreateUser(SecurityUtils.getPersonId());
			personFy.setCreateTime(LocalDateTime.now());
			personFy.insert();
		}
	}

	@Override
	public RewardPerson4C rewardPerson4CPage(Page<FxRewardPersonVo4C> page, Long loginId) {
		RewardPerson4C rewardPerson4C = new RewardPerson4C();
		FxPersonAccount account = fxPersonAccountService.getOne(Wrappers.lambdaQuery(FxPersonAccount.class).eq(FxPersonAccount::getPersonId, loginId));
		FxWithdrawalPerson withdrawalPerson = new FxWithdrawalPerson();
		withdrawalPerson.setStatus(2);
		withdrawalPerson.setPersonId(SecurityUtils.getPersonId());
		page = fxRewardPersonMapper.rewardPerson4CPage(page,withdrawalPerson);
		rewardPerson4C.setPage(page);
		rewardPerson4C.setBalance(account.getBalance());
		BigDecimal money = fxRewardPersonMapper.sumMuney(2,loginId);
		rewardPerson4C.setMoney(money);
		return rewardPerson4C;
	}

	@Override
	public void updateReward(int shopType, Long sjId) {
		fxRewardPersonMapper.updateReward(shopType,sjId);
	}

	@Override
	public FXRewardPersonLogVo selectMoeny() {
		return fxRewardPersonMapper.selectMoeny();
	}

	@Override
	public int insert(FXRewardPersonLogVo fxRewardPersonLogVo) {
		BigDecimal balanceFrozen = fxRewardPersonLogVo.getBalanceFrozen();
		BigDecimal returnMoney = fxRewardPersonLogVo.getReturnMoney();
		BigDecimal balance = balanceFrozen.subtract(returnMoney);
		FxBrandMoneyFlow flow = new FxBrandMoneyFlow();
		String batchNumber = System.currentTimeMillis() + "";
		flow.setBatchNumber(batchNumber);
		flow.setFlowType(0);//0充值1提现
		flow.setBalanceMoney(balance);
		flow.setOrderId(batchNumber);
		flow.setTradeId(batchNumber);
		flow.setWay(2);//充值方式：0线下微信转账1支付宝2后台3银行卡
		flow.setCreateUser(SecurityUtils.getUserId());
		flow.setCreateTime(LocalDateTime.now());
		int i = fxBrandMoneyFlowMapper.updateById(flow);
		return 	i;
	}

	@Override
	public List<FxRewardPersonVo> getExport() {
		return fxRewardPersonMapper.getExport();
	}

	@TxTransaction
	@Transactional(rollbackFor = Exception.class)
	@Override
	public void rewardCard(VOrderCardVO orderCard) {
		boolean update = this.update(Wrappers.lambdaUpdate(FxRewardPerson.class)
				.set(FxRewardPerson::getMoney, orderCard.getReturnMoney()).set(FxRewardPerson::getStatus, FxReturnTypeEnum.RETURN.getValue())
				.eq(FxRewardPerson::getTatId, orderCard.getId()).eq(FxRewardPerson::getShopType, 2));
		fxPersonAccountService.updateFxPersonAccount(orderCard.getPersonId(),0,orderCard.getReturnMoney(),orderCard.getReturnMoney(),null,null,null);
	}

}
